<template>
    <div class="quill-editor">
        <slot name="toolbar"></slot>
        <div ref="editor"></div>
    </div>
</template>

<script>

import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";


// require sources
let Quill = null;
if (process.client) {
    Quill = window.Quill || require('quill')
} else {
    Quill = null;
}


// export
export default {
    name: 'quill-editor',
    data () {
        return {
            _options: {},
            _content: '',
            defaultOptions: {
                theme: 'snow',
                boundary: document.body,
                modules: {
                    toolbar: [
                        ['bold', 'italic', 'underline', 'strike'],
                        ['blockquote', 'code-block'],
                        [{ 'header': 1 }, { 'header': 2 }],
                        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
                        [{ 'script': 'sub' }, { 'script': 'super' }],
                        [{ 'indent': '-1' }, { 'indent': '+1' }],
                        [{ 'direction': 'rtl' }],
                        [{ 'size': ['small', false, 'large', 'huge'] }],
                        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
                        [{ 'color': [] }, { 'background': [] }],
                        [{ 'font': [] }],
                        [{ 'align': [] }],
                        ['clean'],
                        ['link', 'image', 'video']
                    ]
                },
                placeholder: 'Insert text here ...',
                readOnly: false
            }
        }
    },
    props: {
        content: String,
        value: String,
        disabled: {
            type: Boolean,
            default: false
        },
        options: {
            type: Object,
            required: false,
            default: () => ({})
        },
        globalOptions: {
            type: Object,
            required: false,
            default: () => ({})
        }
    },
    mounted () {
        this.initialize()
    },
    beforeDestroy () {
        this.quill = null
        delete this.quill
    },
    methods: {
        // Init Quill instance
        initialize () {
            if (this.$el) {

                const forbiden = (node, Delta) => {

                    let ops = []
                    Delta.ops.forEach(op => {
                        if (!op || op.insert) {
                            // 为空
                        } else if (op.insert.image || op.insert.video || op.insert.audio) {
                            //本地图片会使文件file开头
                            // op.insert.image.includes('file://')
                            // 图片、视频、音频禁止上传
                        } else {
                            ops.push({
                                insert: op.insert,
                            })
                        }
                    })
                    Delta.ops = ops
                    return Delta
                }

                const editorOption = {
                    placeholder: "",
                    theme: "snow", // or 'bubble'
                    modules: {
                        toolbar: {
                            container: [
                                ["bold", "italic", "underline"], // 加粗 斜体 下划线 删除线
                                [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
                                [{ align: "" }, { align: "center" }, { align: "right" }],
                                // ["code", "image"], // 链接、图片、视频
                                ["code"], // 链接、图片、视频
                            ],
                        },
                        clipboard: {
                            matchers: [
                                ['IMG', forbiden],
                                ['VIDEO', forbiden],
                                ['AUDIO', forbiden]
                            ]
                        }
                    },
                }

                // Options
                this._options = Object.assign({}, this.defaultOptions, this.globalOptions, editorOption, this.options)

                // Instance
                this.quill = new Quill(this.$refs.editor, this._options)

                this.quill.enable(false)

                // Set editor content
                if (this.value || this.content) {
                    this.quill.pasteHTML(this.value || this.content)
                }

                // Disabled editor
                if (!this.disabled) {
                    this.quill.enable(true)
                }

                // Mark model as touched if editor lost focus
                this.quill.on('selection-change', range => {
                    if (!range) {
                        this.$emit('blur', this.quill)
                    } else {
                        this.$emit('focus', this.quill)
                    }
                })

                // Update model if text changes
                this.quill.on('text-change', (delta, oldDelta, source) => {
                    let html = this.quill.root.innerHTML;
                    const quill = this.quill
                    const text = this.quill.getText()
                    if (html === '<p><br></p>') html = ''
                    this._content = html
                    this.$emit('input', this._content)
                    this.$emit('change', { html, text, quill })
                })

                // Emit ready event
                this.$emit('ready', this.quill)
            }
        },
    },
    watch: {
        // Watch content change
        content (newVal, oldVal) {
            if (this.quill) {
                if (newVal && newVal !== this._content) {
                    this._content = newVal
                    this.quill.pasteHTML(newVal)
                } else if (!newVal) {
                    this.quill.setText('')
                }
            }
        },
        // Watch content change
        value (newVal, oldVal) {
            if (this.quill) {
                if (newVal && newVal !== this._content) {
                    this._content = newVal
                    this.quill.pasteHTML(newVal)
                } else if (!newVal) {
                    this.quill.setText('')
                }
            }
        },
        // Watch disabled change
        disabled (newVal, oldVal) {
            if (this.quill) {
                this.quill.enable(!newVal)
            }
        }
    }
}
</script>

<style>
.quill-editor {
    line-height: normal;
}
.ql-container {
    min-height: 200px;
}
.ql-container ul {
    padding: 0 !important;
}

.ql-snow.ql-toolbar button {
    width: 32px;
    height: 32px;
    line-height: 32px;
    padding: 5px;
    border-radius: 4px;
    margin: 0 6px;
}

.ql-snow.ql-toolbar button:hover .ql-stroke,
.ql-snow.ql-toolbar button:focus .ql-stroke {
    stroke: #ea4c89;
}

.ql-snow.ql-toolbar button:hover .ql-fill,
.ql-snow.ql-toolbar button:focus .ql-fill {
    fill: #ea4c89;
}

.ql-snow.ql-toolbar button.ql-active {
    background: #ea4c89;
}
.ql-snow.ql-toolbar button.ql-active .ql-fill {
    fill: #fff;
}
.ql-snow.ql-toolbar button.ql-active .ql-stroke {
    stroke: #fff;
}

/* 
.ql-snow.ql-toolbar button:hover .ql-fill,
.ql-snow .ql-toolbar button:hover .ql-fill,
.ql-snow.ql-toolbar button:focus .ql-fill,
.ql-snow .ql-toolbar button:focus .ql-fill,
.ql-snow.ql-toolbar button.ql-active .ql-fill,
.ql-snow .ql-toolbar button.ql-active .ql-fill,
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-fill,
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-fill,
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-fill,
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-fill,
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-fill,
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-fill,
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-fill,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-fill,
.ql-snow.ql-toolbar button:hover .ql-stroke.ql-fill,
.ql-snow .ql-toolbar button:hover .ql-stroke.ql-fill,
.ql-snow.ql-toolbar button:focus .ql-stroke.ql-fill,
.ql-snow .ql-toolbar button:focus .ql-stroke.ql-fill,
.ql-snow.ql-toolbar button.ql-active .ql-stroke.ql-fill,
.ql-snow .ql-toolbar button.ql-active .ql-stroke.ql-fill,
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke.ql-fill,
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke.ql-fill,
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke.ql-fill,
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill {
    fill: #fff;
} */

/* .ql-snow.ql-toolbar button:hover .ql-stroke,
.ql-snow .ql-toolbar button:hover .ql-stroke,
.ql-snow.ql-toolbar button:focus .ql-stroke,
.ql-snow .ql-toolbar button:focus .ql-stroke,
.ql-snow.ql-toolbar button.ql-active .ql-stroke,
.ql-snow .ql-toolbar button.ql-active .ql-stroke,
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke,
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke,
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke,
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke,
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke,
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke,
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke,
.ql-snow.ql-toolbar button:hover .ql-stroke-miter,
.ql-snow .ql-toolbar button:hover .ql-stroke-miter,
.ql-snow.ql-toolbar button:focus .ql-stroke-miter,
.ql-snow .ql-toolbar button:focus .ql-stroke-miter,
.ql-snow.ql-toolbar button.ql-active .ql-stroke-miter,
.ql-snow .ql-toolbar button.ql-active .ql-stroke-miter,
.ql-snow.ql-toolbar .ql-picker-label:hover .ql-stroke-miter,
.ql-snow .ql-toolbar .ql-picker-label:hover .ql-stroke-miter,
.ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,
.ql-snow .ql-toolbar .ql-picker-label.ql-active .ql-stroke-miter,
.ql-snow.ql-toolbar .ql-picker-item:hover .ql-stroke-miter,
.ql-snow .ql-toolbar .ql-picker-item:hover .ql-stroke-miter,
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter {
    stroke: #ea4c89;
} */
</style>
